package com.example.oracle.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.example.oracle.helper.OracleMapper;
import com.github.pagehelper.PageInterceptor;

@org.springframework.context.annotation.Configuration
@MapperScan(basePackages="com.example.oracle.dao", annotationClass=OracleMapper.class, sqlSessionTemplateRef = "sqlSessionTemplate"+OracleDataSourceConfig.SUFFIX)
public class OracleDataSourceConfig {

	protected static final String SUFFIX = "-oracle";
	
	public static final String transactionManagerName= "transactionManager"+SUFFIX;
	
	@Bean("dataSource" + SUFFIX)
    @ConfigurationProperties("spring.datasource" + SUFFIX)
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
 
    @Bean("mybatisProperties" + SUFFIX)
    @ConfigurationProperties("mybatis" + SUFFIX)
    public MybatisProperties mybatisProperties() {
        return new MybatisProperties();
    }
 
    @Bean(transactionManagerName)
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
 
    @Bean("sqlSessionFactory" + SUFFIX)
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisProperties properties = mybatisProperties();
        DataSource ds = dataSource();
 
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(ds);
        factory.setVfs(SpringBootVFS.class);
        Configuration configuration = properties.getConfiguration();
        if (configuration == null && !StringUtils.hasText(properties.getConfigLocation())) {
            configuration = new Configuration();
        }
 
        factory.setConfiguration(configuration);
        if (properties.getConfiguration() != null) {
            factory.setConfiguration(properties.getConfiguration());
        }
        if (StringUtils.hasLength(properties.getTypeAliasesPackage())) {
            factory.setTypeAliasesPackage(properties.getTypeAliasesPackage());
        }
        if (StringUtils.hasLength(properties.getTypeHandlersPackage())) {
            factory.setTypeHandlersPackage(properties.getTypeHandlersPackage());
        }
        if (!ObjectUtils.isEmpty(properties.resolveMapperLocations())) {
            factory.setMapperLocations(properties.resolveMapperLocations());
        }
        
        Interceptor interceptor = new PageInterceptor();
        Properties p = new Properties();
        //数据库
        p.setProperty("helperDialect", "oracle");
        //是否将参数offset作为PageNum使用
        p.setProperty("offsetAsPageNum", "true");
        //是否进行count查询
        p.setProperty("rowBoundsWithCount", "true");
        //是否分页合理化
        p.setProperty("reasonable", "false");
        interceptor.setProperties(p);
        factory.setPlugins(new Interceptor[] {interceptor});
        return factory.getObject();
    }
 
    @Bean("sqlSessionTemplate" + SUFFIX)
    public SqlSessionTemplate sqlSessionTemplate() throws Exception {
        SqlSessionFactory sqlSessionFactory = sqlSessionFactory();
        MybatisProperties properties = mybatisProperties();
 
        ExecutorType executorType = properties.getExecutorType();
        if (executorType != null) {
            return new SqlSessionTemplate(sqlSessionFactory, executorType);
        } else {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }

}
